import logging
import time

logger = logging.getLogger(__name__)

class RelayManagerLgpio:
    """继电器管理器 - 使用 lgpio，树莓派5官方推荐"""
    
    def __init__(self):
        self.relays = {}
        self._initialized = False
        self._gpio_available = False
        self._lgpio_handle = None
        
        # 继电器配置
        self.relay_config = {
            'relay_1': {'pin': 17, 'enabled': True},
            'relay_2': {'pin': 18, 'enabled': False},
            'relay_3': {'pin': 27, 'enabled': False},
            'relay_4': {'pin': 22, 'enabled': False}
        }
    
    def initialize(self):
        """初始化"""
        if self._initialized:
            return
            
        print("🍓 树莓派5继电器管理器初始化 (lgpio)...")
        
        # 检测 lgpio
        self._gpio_available = self._check_lgpio()
        
        if self._gpio_available:
            self._initialize_real_relays()
            print("✅ 真实继电器初始化成功")
        else:
            self._initialize_simulated_relays()
            print("🔧 使用模拟继电器模式")
        
        self._initialized = True
        print(f"✅ 继电器管理器初始化完成 - 模式: {'真实硬件' if self._gpio_available else '模拟'}")
    
    def _check_lgpio(self):
        """检查 lgpio 是否可用"""
        try:
            import lgpio
            
            # 打开GPIO芯片
            self._lgpio_handle = lgpio.gpiochip_open(0)
            if self._lgpio_handle >= 0:
                print("✅ lgpio 可用，芯片打开成功")
                return True
            else:
                print("❌ lgpio 芯片打开失败")
                return False
                
        except Exception as e:
            print(f"❌ lgpio 不可用: {e}")
            return False
    
    def _initialize_real_relays(self):
        """初始化真实继电器"""
        try:
            import lgpio
            
            for relay_id, config in self.relay_config.items():
                if config['enabled']:
                    # 设置GPIO为输出模式
                    lgpio.gpio_claim_output(self._lgpio_handle, config['pin'])
                    # 初始状态为关闭
                    lgpio.gpio_write(self._lgpio_handle, config['pin'], 0)
                    
                    self.relays[relay_id] = LgpioRelay(relay_id, config['pin'], self._lgpio_handle)
                    print(f"✅ 初始化真实继电器: {relay_id} (GPIO{config['pin']})")
                else:
                    self.relays[relay_id] = SimulatedRelay(relay_id, config['pin'])
                    print(f"🔧 初始化模拟继电器: {relay_id} (第二步禁用)")
                    
        except Exception as e:
            print(f"❌ 真实继电器初始化失败: {e}")
            self._initialize_simulated_relays()
            self._gpio_available = False
    
    def _initialize_simulated_relays(self):
        """初始化模拟继电器"""
        for relay_id, config in self.relay_config.items():
            self.relays[relay_id] = SimulatedRelay(relay_id, config['pin'])
    
    def control_relay(self, relay_id, action):
        """控制继电器"""
        if not self._initialized:
            self.initialize()
        
        if relay_id not in self.relays:
            return {'success': False, 'error': f'继电器 {relay_id} 不存在'}
        
        if not self.relay_config[relay_id]['enabled']:
            return {
                'success': False, 
                'error': f'继电器 {relay_id} 在第二步中未启用',
                'mode': 'simulation'
            }
        
        relay = self.relays[relay_id]
        
        try:
            if action == 'on':
                result = relay.turn_on()
            elif action == 'off':
                result = relay.turn_off()
            else:  # toggle
                result = relay.toggle()
            
            return {
                'success': True,
                'relay': relay_id,
                'state': result['state'],
                'mode': 'hardware' if self._gpio_available else 'simulation',
                'message': result['message']
            }
            
        except Exception as e:
            return {
                'success': False,
                'error': str(e),
                'mode': 'hardware' if self._gpio_available else 'simulation'
            }
    
    def get_relay_state(self, relay_id):
        """获取继电器状态"""
        if not self._initialized:
            self.initialize()
        
        if relay_id not in self.relays:
            raise ValueError(f"继电器 {relay_id} 不存在")
        
        return self.relays[relay_id].get_state()
    
    def get_all_states(self):
        """获取所有继电器状态"""
        if not self._initialized:
            self.initialize()
        
        states = {}
        for relay_id in self.relays:
            states[relay_id] = self.get_relay_state(relay_id)
        
        return states
    
    def get_system_info(self):
        """获取系统信息"""
        if not self._initialized:
            self.initialize()
        
        enabled_relays = [rid for rid, config in self.relay_config.items() if config['enabled']]
        
        return {
            'mode': 'hardware' if self._gpio_available else 'simulation',
            'board': 'Raspberry Pi 5',
            'library': 'lgpio (官方推荐)',
            'gpio_available': self._gpio_available,
            'enabled_relays': enabled_relays,
            'step': 2
        }
    
    def cleanup(self):
        """清理资源"""
        if self._lgpio_handle is not None:
            try:
                import lgpio
                lgpio.gpiochip_close(self._lgpio_handle)
                print("✅ lgpio 资源已清理")
            except Exception as e:
                print(f"❌ lgpio 清理失败: {e}")
        
        self._initialized = False
        self._lgpio_handle = None


class LgpioRelay:
    """使用 lgpio 控制继电器"""
    
    def __init__(self, relay_id, pin, lgpio_handle):
        import lgpio
        self.relay_id = relay_id
        self.pin = pin
        self._lgpio_handle = lgpio_handle
        self._state = False
        
        print(f"🔌 lgpio继电器: {relay_id} (GPIO{pin})")
    
    def turn_on(self):
        """开启继电器"""
        import lgpio
        lgpio.gpio_write(self._lgpio_handle, self.pin, 1)
        self._state = True
        message = f"真实继电器 {self.relay_id} 已开启"
        print(f"⚡ {message}")
        return {'state': True, 'message': message}
    
    def turn_off(self):
        """关闭继电器"""
        import lgpio
        lgpio.gpio_write(self._lgpio_handle, self.pin, 0)
        self._state = False
        message = f"真实继电器 {self.relay_id} 已关闭"
        print(f"💤 {message}")
        return {'state': False, 'message': message}
    
    def toggle(self):
        """切换继电器状态"""
        if self._state:
            return self.turn_off()
        else:
            return self.turn_on()
    
    def get_state(self):
        """获取状态"""
        import lgpio
        try:
            # 读取当前状态
            current_state = lgpio.gpio_read(self._lgpio_handle, self.pin)
            self._state = bool(current_state)
        except:
            # 如果读取失败，使用内部状态
            pass
        return self._state
    
    def close(self):
        """关闭资源"""
        # 资源清理在管理器层面处理
        pass


class SimulatedRelay:
    """模拟继电器"""
    
    def __init__(self, relay_id, pin):
        self.relay_id = relay_id
        self.pin = pin
        self._state = False
        print(f"🔧 模拟继电器: {relay_id} (GPIO{pin})")
    
    def turn_on(self):
        self._state = True
        message = f"模拟继电器 {self.relay_id} 已开启"
        print(f"🔧 {message}")
        return {'state': True, 'message': message}
    
    def turn_off(self):
        self._state = False
        message = f"模拟继电器 {self.relay_id} 已关闭"
        print(f"🔧 {message}")
        return {'state': False, 'message': message}
    
    def toggle(self):
        if self._state:
            return self.turn_off()
        else:
            return self.turn_on()
    
    def get_state(self):
        return self._state
    
    def close(self):
        pass


# 全局实例
relay_manager = RelayManagerLgpio()